<template>
  <div id="community-follow">
    <div v-if="followData.length === 0 && !loading" class="empty-state">
      <van-empty description="暂无关注内容">
        <van-button round type="primary" size="small" @click="fetchFollowData">刷新</van-button>
      </van-empty>
    </div>

    <div class="not-logged-in" :class="{ 'disabled': isLoggedIn }" @click="handleNotLoggedInClick">
      <van-icon name="friends" />
      <span>{{ isLoggedIn ? '您还没有关注的用户' : '登录后探索更多精彩' }}</span>
    </div>

    <div v-if="followData.length > 0" class="follow-content">
      <div class="follow-list">
        <div class="follow-item" v-for="(item, index) in followData" :key="index"
          @click="handleFollowVideoClick(index)">
          <div class="item-cover">
            <img :src="item.cover?.feed || ''" alt="">
            <van-icon name="play-circle-o" color="#fff" size="30" />
            <div class="item-duration">{{ formatDuration(item.duration) }}</div>
          </div>
          <div class="item-info">
            <div class="item-title">{{ item.title || '' }}</div>
            <div class="item-author">
              <div class="author-avatar"
                :style="{ backgroundImage: item.author?.icon ? `url(${item.author.icon})` : 'none' }"></div>
              <div class="author-info">
                <div class="author-name">{{ item.author?.name || '未知用户' }}</div>
                <div class="item-meta">
                  <span>{{ item.category || '' }}</span>
                  <span>·</span>
                  <span>{{ formatCollectionCount(item.consumption?.collectionCount) }}收藏</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <van-loading v-if="loading" class="loading" type="spinner" color="#1989fa" />
    <div class="loading" v-if="isLoadingMore">
      <van-loading type="spinner" color="#1989fa" />
      <span style="margin-left:8px;">数据正在加载中...</span>
    </div>

    <div v-if="!hasMore && followData.length > 0" class="no-more">
      <p>没有更多了</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onActivated, onBeforeUnmount, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { getFollow, getByFullUrl } from '@/api/api';
import { useVideoStore } from '@/stores/counter';
import { showToast } from 'vant';

const router = useRouter(); // 路由实例
const videoStore = useVideoStore(); // 视频状态管理

// 数据状态
const followData = ref<any[]>([]); // 关注列表数据
const loading = ref(false); // 初始加载状态
const nextPageUrl = ref<string | null>(null); // 下一页URL
const isLoadingMore = ref(false); // 是否正在加载更多
const hasMore = ref(true); // 是否还有更多数据
const isLoggedIn = ref(false); // 登录状态

// 滚动相关
let lastToastTime = 0; // 上次提示时间（用于防抖）
const TOAST_INTERVAL = 2000; // 提示间隔时间（ms）
let scrollContainer: HTMLElement | null = null; // 滚动容器DOM引用

// 格式化时长：将秒数转换为 MM:SS 格式
const formatDuration = (seconds: number): string => {
  if (!seconds || seconds < 0) return '00:00';
  const minutes = Math.floor(seconds / 60); // 分钟数
  const remainingSeconds = seconds % 60; // 剩余秒数
  return `${String(minutes).padStart(2, '0')}:${String(remainingSeconds).padStart(2, '0')}`;
};

// 格式化收藏数：将数字转换为带单位的字符串（如：10000 -> 1.0万）
const formatCollectionCount = (count: number): string => {
  if (!count) return '0';
  if (count >= 10000) return `${(count / 10000).toFixed(1)}万`;
  return count.toString();
};

// 检查登录状态
const checkLoginStatus = () => {
  isLoggedIn.value = localStorage.getItem('isLoggedIn') === 'true';
};

// 处理未登录状态点击：弹出登录注册模块
const handleNotLoggedInClick = () => {
  if (!isLoggedIn.value) {
    window.dispatchEvent(new CustomEvent('showLoginRegister', {
      detail: { routePath: router.currentRoute.value.path }
    }));
  }
};

// 处理关注页视频点击：设置当前视频并跳转到视频播放页
const handleFollowVideoClick = (index: number) => {
  videoStore.setCurrentVideo(followData.value[index]);
  router.push('/video');
};

// 获取关注内容：从API获取数据并提取视频信息
const fetchFollowData = async () => {
  loading.value = true;
  try {
    const data: any = await getFollow();
    if (data.itemList && data.itemList.length > 0) {
      followData.value = [];
      data.itemList.forEach((item: any) => {
        // 处理视频集合类型
        if (item.type === 'videoCollectionWithBrief' && item.data?.itemList) {
          item.data.itemList.forEach((video: any) => {
            if (video.type === 'video' && video.data) {
              // 验证必要字段存在（必须有封面图）
              if (video.data.cover && video.data.cover.feed) {
                followData.value.push(video.data);
              }
            }
          });
        } else if (item.type === 'video' && item.data) {
          // 处理单个视频类型
          if (item.data.cover && item.data.cover.feed) {
            followData.value.push(item.data);
          }
        }
      });
    }
    nextPageUrl.value = data.nextPageUrl || null;
    hasMore.value = Boolean(nextPageUrl.value);
  } catch (err) {
    console.error('获取关注内容失败:', err);
  } finally {
    loading.value = false;
  }
};

// 规范化下一页URL：将完整URL转换为相对路径
const normalizeNextUrl = (url: string): string => {
  if (!url) return '';
  try {
    const u = new URL(url);
    return u.pathname + u.search; // 返回路径和查询参数
  } catch {
    return url;
  }
};

// 加载更多数据：滚动到底部时触发
const loadMore = async () => {
  if (isLoadingMore.value || !hasMore.value || !nextPageUrl.value) return;
  isLoadingMore.value = true;
  try {
    // 处理URL：如果是完整URL则规范化，否则直接使用
    let url = nextPageUrl.value;
    if (!url.startsWith('http://') && !url.startsWith('https://')) {
      url = normalizeNextUrl(nextPageUrl.value);
      url = url.startsWith('/') ? url : `/${url}`;
    }
    const data: any = await getByFullUrl(url);
    if (data?.itemList?.length) {
      data.itemList.forEach((item: any) => {
        // 处理视频集合类型
        if (item.type === 'videoCollectionWithBrief' && item.data?.itemList) {
          item.data.itemList.forEach((video: any) => {
            if (video.type === 'video' && video.data) {
              // 验证必要字段存在，确保数据完整性
              if (video.data.cover && video.data.cover.feed) {
                followData.value.push(video.data);
              }
            }
          });
        } else if (item.type === 'video' && item.data) {
          // 处理单个视频类型
          if (item.data.cover && item.data.cover.feed) {
            followData.value.push(item.data);
          }
        }
      });
    }
    nextPageUrl.value = data.nextPageUrl || null;
    hasMore.value = Boolean(nextPageUrl.value);
  } catch (e) {
    console.error('关注页加载更多失败:', e);
  } finally {
    isLoadingMore.value = false;
  }
};

// 处理滚动事件：监听滚动到底部，触发加载更多或显示提示
const handleScroll = () => {
  if (!scrollContainer) {
    scrollContainer = document.querySelector('.router-view-container > div') as HTMLElement;
  }
  if (!scrollContainer) return;

  const scrollTop = scrollContainer.scrollTop; // 当前滚动位置
  const viewH = scrollContainer.clientHeight; // 可视区域高度
  const docH = scrollContainer.scrollHeight; // 文档总高度

  // 当滚动到距离底部 120px 时触发
  if (scrollTop + viewH >= docH - 120) {
    if (!hasMore.value || !nextPageUrl.value) {
      // 没有更多数据，显示提示
      const now = Date.now();
      if (now - lastToastTime > TOAST_INTERVAL) {
        showToast('已经到底了哦~');
        lastToastTime = now;
      }
      return;
    }
    loadMore();
  }
};

// 绑定滚动事件：在DOM更新后绑定滚动监听器
const bindScrollEvent = () => {
  // 先移除之前的监听器
  if (scrollContainer) {
    scrollContainer.removeEventListener('scroll', handleScroll as any);
    scrollContainer = null;
  }

  // 等待 DOM 更新后再绑定滚动事件
  nextTick(() => {
    setTimeout(() => {
      scrollContainer = document.querySelector('.router-view-container > div') as HTMLElement;
      if (scrollContainer) {
        scrollContainer.addEventListener('scroll', handleScroll, { passive: true });
      }
    }, 100);
  });
};

// 处理登录成功
const handleLoginSuccess = () => {
  checkLoginStatus();
};

// 组件挂载时：获取数据并绑定滚动事件
onMounted(() => {
  checkLoginStatus();
  fetchFollowData();
  bindScrollEvent();
  // 监听登录成功事件
  window.addEventListener('loginSuccess', handleLoginSuccess);
});

// 组件激活时重新绑定滚动事件
onActivated(() => {
  checkLoginStatus();
  bindScrollEvent();
});

// 清理滚动事件监听器
onBeforeUnmount(() => {
  if (scrollContainer) {
    scrollContainer.removeEventListener('scroll', handleScroll as any);
    scrollContainer = null;
  }
  // 移除登录成功事件监听
  window.removeEventListener('loginSuccess', handleLoginSuccess);
});
</script>

<style scoped lang="less">
#community-follow {
  width: 100%;
  min-height: 88vh;
  padding-bottom: 2vh;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 60vh;
}

.not-logged-in {
  width: 100%;
  height: 20vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #cfcfcf;
  margin-top: 6vh;
  margin-bottom: 2vh;
  border-bottom: 1px solid #eee;
  cursor: pointer;
  transition: opacity 0.2s;

  &:active:not(.disabled) {
    opacity: 0.7;
  }

  &.disabled {
    cursor: not-allowed;
    pointer-events: none;
  }

  i {
    font-size: 50px;
  }

  span {
    font-size: 14px;
  }
}

.follow-content {
  padding: 2vh 4vw 6vh;
  box-sizing: border-box;

  .follow-list {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 3vh;
    padding: 0;
    box-sizing: border-box;

    .follow-item {
      width: 100%;
      cursor: pointer;
      transition: transform 0.2s;

      &:active {
        transform: scale(0.98);
      }

      .item-cover {
        position: relative;
        width: 100%;
        border-radius: 8px;
        overflow: hidden;

        img {
          width: 100%;
          display: block;
        }

        >i {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          opacity: 0.8;
        }

        .item-duration {
          position: absolute;
          bottom: 8px;
          right: 8px;
          background: rgba(0, 0, 0, 0.6);
          color: #fff;
          padding: 2px 6px;
          border-radius: 4px;
          font-size: 10px;
        }
      }

      .item-info {
        padding: 1vh 0;
        box-sizing: border-box;

        .item-title {
          font-size: 14px;
          font-weight: 500;
          margin-bottom: 1vh;
          display: -webkit-box;
          -webkit-line-clamp: 2;
          line-clamp: 2;
          -webkit-box-orient: vertical;
          overflow: hidden;
        }

        .item-author {
          display: flex;
          align-items: center;
          gap: 10px;

          .author-avatar {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background-size: cover;
            background-position: center;
            flex-shrink: 0;
          }

          .author-info {
            flex: 1;

            .author-name {
              font-size: 12px;
              font-weight: 500;
              margin-bottom: 4px;
            }

            .item-meta {
              font-size: 10px;
              color: #999;
              display: flex;
              align-items: center;
              gap: 4px;
            }
          }
        }
      }
    }
  }
}

.loading {
  display: flex;
  justify-content: center;
  padding: 4vh 0;
  box-sizing: border-box;
}

.no-more {
  width: 100%;
  padding: 20px 0;
  text-align: center;
  color: #999;
  font-size: 12px;
  clear: both;
}
</style>
